package main

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
)

func handleRequest(w *httptest.ResponseRecorder, req *http.Request) {
	app := NewApp()
	app.Router.ServeHTTP(w, req)
}

type AlbumTest struct {
	ID     string  `json:"id"`
	Title  string  `json:"title"`
	Artist string  `json:"artist"`
	Price  float64 `json:"price"`
}

func TestCreateAlbum(t *testing.T) {
	album := AlbumTest{
		ID:     "4",
		Title:  "The Modern Sound of Betty Carter",
		Artist: "Betty Carter",
		Price:  49.99,
	}

	body, _ := json.Marshal(album)
	req, _ := http.NewRequest("POST", "/albums", bytes.NewBuffer(body))
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusCreated {
		t.Errorf("expected status code %d, got %d", http.StatusCreated, w.Code)
	}

	var createdAlbum AlbumTest
	err := json.Unmarshal(w.Body.Bytes(), &createdAlbum)
	if err != nil {
		t.Errorf("failed to unmarshal response body: %v", err)
	}

	if createdAlbum != album {
		t.Errorf("expected album: %v, got: %v", album, createdAlbum)
	}
}

func TestGetAlbums(t *testing.T) {
	req, _ := http.NewRequest("GET", "/albums", nil)
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code)
	}

	// Add assertions to check the response body if needed
}

func TestGetAlbumByID(t *testing.T) {
	req, _ := http.NewRequest("GET", "/albums/1", nil)
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code)
	}

	// Add assertions to check the response body if needed
}

func TestGetAlbumNotFound(t *testing.T) {
	req, _ := http.NewRequest("GET", "/albums/999", nil)
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusNotFound {
		t.Errorf("expected status code %d, got %d", http.StatusNotFound, w.Code)
	}
}

func TestDeleteAlbumByID(t *testing.T) {
	req, _ := http.NewRequest("DELETE", "/albums/2", nil)
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusNoContent {
		t.Errorf("expected status code %d, got %d", http.StatusNoContent, w.Code)
	}
}

func TestDeleteAlbumNotFound(t *testing.T) {
	req, _ := http.NewRequest("DELETE", "/albums/999", nil)
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusNotFound {
		t.Errorf("expected status code %d, got %d", http.StatusNotFound, w.Code)
	}
}

func TestUpdateAlbumByID(t *testing.T) {
	album := AlbumTest{
		ID:     "1",
		Title:  "Updated AlbumTest Title",
		Artist: "Updated Artist",
		Price:  99.99,
	}

	body, _ := json.Marshal(album)
	req, _ := http.NewRequest("PUT", "/albums/1", bytes.NewBuffer(body))
	w := httptest.NewRecorder()
	handleRequest(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code)
	}

	var updatedAlbum AlbumTest
	err := json.Unmarshal(w.Body.Bytes(), &updatedAlbum)
	if err != nil {
		t.Errorf("failed to unmarshal response body: %v", err)
	}

	if updatedAlbum != album {
		t.Errorf("expected album: %v, got: %v", album, updatedAlbum)
	}
}
